use proc_macro::TokenStream;

#[proc_macro]
pub fn make_answer(_item: TokenStream) -> TokenStream {
    "fn answer() -> u32 { 42 }".parse().unwrap()
}
use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput, Expr, Fields, Ident, ItemFn};

#[proc_macro]
pub fn my_function_macro(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as Expr);

    let expanded = quote! {
        {
            println!("This is a function-like macro with input: {:?}", #input);
            #input
        }
    };

    TokenStream::from(expanded)
}
#[proc_macro]
pub fn my_macro(input: TokenStream) -> TokenStream {
    let parsed = parse_macro_input!(input as syn::ItemFn);
    let ident = &parsed.sig.ident;

    let expanded = quote! {
        fn #ident() {
            println!("Hello, World!");
        }
    };

    TokenStream::from(expanded)
}
#[proc_macro]
pub fn generate_greeting(input: TokenStream) -> TokenStream {
    // 解析输入的标识符
    let name: Ident = parse_macro_input!(input as Ident);

    // 生成问候语句
    let expanded = quote! {
        println!("Hello, {}!", #name);
    };

    // 返回生成的代码
    TokenStream::from(expanded)
}

#[proc_macro_attribute]
pub fn print_fields(attr: TokenStream,item: TokenStream) -> TokenStream {
    // 解析输入的 TokenStream 为 DeriveInput
    let input = parse_macro_input!(item as DeriveInput);

    // 获取结构体的名字
    let name = &input.ident;

    // 获取结构体的字段
    let fields = match input.data {
        Data::Struct(ref data) => match data.fields {
            Fields::Named(ref fields) => &fields.named,
            _ => panic!("print_fields 属性宏仅支持具名字段的结构体"),
        },
        _ => panic!("print_fields 属性宏仅支持结构体"),
    };

    // 生成字段名称的字符串字面量
    let field_names = fields.iter().map(|field| {
        let field_name = &field.ident;
        // quote! { format!("{}: {:?}", stringify!(#field_name), self.#field_name) }
        quote! { stringify!(#field_name) }
    });

    // 生成新的代码
    let expanded = quote! {
        #input//如果是派生宏就不需要加这个，属性宏会吧原来的结构体定义给替换掉

        impl #name {
            pub fn print_fields(&self) {
                println!("Fields: {:?}", vec![#(#field_names),*]);
            }
        }
    };

    // 返回生成的代码
    TokenStream::from(expanded)
}